#include "DeadLineTimer.h"
#include "Watcher.h"
#include "LoopService.h"
#include "event.h"




DeadLineTimer::DeadLineTimer(LoopService* evloop, int timeout, bool periodic)
	: loop_(evloop), timeout_(timeout),  periodic_(periodic)
{
}

DeadLineTimerPtr DeadLineTimer::create(LoopService* evloop, int timeout, bool periodic)
{
    DeadLineTimerPtr it(new DeadLineTimer(evloop, timeout, periodic));
	it->self_ = it;
	return it;
}

void DeadLineTimer::start(const Functor& f)
{
    functor_ = f;
	auto pf = [this]() {
		timer_ = std::make_shared<TimerEventWatcher>(loop_, 
            std::bind(&DeadLineTimer::_on_timer_triggered, shared_from_this()), timeout_);
		timer_->set_cancel_Callback(std::bind(&DeadLineTimer::_on_canceled, shared_from_this()));
		timer_->init();
		timer_->async_wait();
	};
	loop_->dispatch(pf);
}

void DeadLineTimer::cancel()
{
	if (timer_) {
		loop_->post(std::bind(&TimerEventWatcher::cancel, timer_));
	}
}

void DeadLineTimer::_on_timer_triggered()
{
	functor_(std::error_code());

	if (periodic_) {
		timer_->async_wait();
	}
	else {
		functor_ = Functor();	
		timer_.reset();
		self_.reset();
	}
}

void DeadLineTimer::_on_canceled()
{
	periodic_ = false;
	if (functor_) {
		functor_(std::error_code(std::make_error_code(std::errc::operation_canceled)));
	}
	functor_ = Functor();
	timer_.reset();
	self_.reset();
}




